home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / INDENT3.ARJ / ARGS.C next >
C/C++ Source or Header  |  1992-08-04  |  9KB  |  302 lines

  1. /* Copyright (c) 1980 Regents of the University of California. All rights
  2.  * reserved.  The Berkeley software License Agreement specifies the terms and
  3.  * conditions for redistribution. */
  4.  
  5. #ifndef lint
  6. static char sccsid[] = "@(#)args.c      5.2 (Berkeley) 9/10/85";
  7. #endif not lint
  8.  
  9. /* Argument scanning and profile reading code.  Default parameters are set
  10.  * here as well. */
  11.  
  12. #include "indent_globs.h"
  13. #include <sys/types.h>
  14. #include <ctype.h>
  15.  
  16. /* profile types */
  17. typedef enum profile {
  18.     PRO_SPECIAL = 1,
  19.     PRO_BOOL,
  20.     PRO_INT,
  21.     PRO_SETTINGS,
  22. } profile;
  23.  
  24. /* profile specials for specials and booleans */
  25. typedef enum special {
  26.     OFF = 0,
  27.     ON,
  28.     IGN,
  29.     CLI,
  30.     STDIN,
  31.     KEY,
  32. } special;
  33.  
  34. /* N.B.: because of the way the table here is scanned, options whose names
  35.  * are substrings of other options must occur later; that is, with -lp vs -l,
  36.  * -lp must be first.  Also, while (most) booleans occur more than once, the
  37.  * last default value is the one actually assigned. */
  38. struct pro {
  39.     char *p_name;        /* name, eg -bl, -cli */
  40.     profile p_type;        /* type (int, bool, special) */
  41.     int p_default;        /* the default value (if int) */
  42.     special p_special;        /* depends on type */
  43.     int *p_obj;            /* the associated variable */
  44.     char *p_data;        /* data for the option */
  45. };
  46.  
  47. struct pro pro[] = {
  48.     "npro", PRO_SPECIAL, 0, IGN, 0, NULL,
  49.     "lc", PRO_INT, 0, 0, &block_comment_max_col, NULL,
  50.     "lp", PRO_BOOL, true, ON, &lineup_to_parens, NULL,
  51.     "nlp", PRO_BOOL, true, OFF, &lineup_to_parens, NULL,
  52.     "l", PRO_INT, 78, 0, &max_col, NULL,
  53.     "psl", PRO_BOOL, true, ON, &procnames_start_line, NULL,
  54.     "npsl", PRO_BOOL, true, OFF, &procnames_start_line, NULL,
  55.     "fc1", PRO_BOOL, true, ON, &format_col1_comments, NULL,
  56.     "nfc1", PRO_BOOL, true, OFF, &format_col1_comments, NULL,
  57.     "fca", PRO_BOOL, true, ON, &format_comments, NULL,
  58.     "nfca", PRO_BOOL, true, OFF, &format_comments, NULL,
  59.     "pcs", PRO_BOOL, false, ON, &proc_calls_space, NULL,
  60.     "npcs", PRO_BOOL, false, OFF, &proc_calls_space, NULL,
  61.     "ip", PRO_BOOL, true, ON, &ps.indent_parameters, NULL,
  62.     "nip", PRO_BOOL, true, OFF, &ps.indent_parameters, NULL,
  63. /* see set_defaults for initialization of -cli */
  64.     "cli", PRO_SPECIAL, 0, CLI, 0, NULL,
  65.     "ci", PRO_INT, 0, 0, &continuation_indent, NULL,
  66.     "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline, NULL,
  67.     "ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline, NULL,
  68.     "i", PRO_INT, 8, 0, &ps.ind_size, NULL,
  69.     "cd", PRO_INT, 0, 0, &ps.decl_com_ind, NULL,
  70.     "ce", PRO_BOOL, true, ON, &cuddle_else, NULL,
  71.     "nce", PRO_BOOL, true, OFF, &cuddle_else, NULL,
  72.     "c", PRO_INT, 33, 0, &ps.com_ind, NULL,
  73.     "v", PRO_BOOL, false, ON, &verbose, NULL,
  74.     "nv", PRO_BOOL, false, OFF, &verbose, NULL,
  75.     "dj", PRO_BOOL, false, ON, &ps.ljust_decl, NULL,
  76.     "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl, NULL,
  77. /* don't ask *me* why -bc/-nbc is backwards.... */
  78.     "bc", PRO_BOOL, true, OFF, &ps.leave_comma, NULL,
  79.     "nbc", PRO_BOOL, true, ON, &ps.leave_comma, NULL,
  80.     "di", PRO_INT, 16, 0, &ps.decl_indent, NULL,
  81.     "d", PRO_INT, 0, 0, &ps.unindent_displace, NULL,
  82.     "br", PRO_BOOL, true, ON, &btype_2, NULL,
  83.     "bl", PRO_BOOL, true, OFF, &btype_2, NULL,
  84.     "st", PRO_SPECIAL, 0, STDIN, 0, NULL,
  85.     "ei", PRO_BOOL, true, ON, &ps.else_if, NULL,
  86.     "nei", PRO_BOOL, true, OFF, &ps.else_if, NULL,
  87.     "sc", PRO_BOOL, true, ON, &star_comment_cont, NULL,
  88.     "nsc", PRO_BOOL, true, OFF, &star_comment_cont, NULL,
  89.     "bap", PRO_BOOL, false, ON, &blanklines_after_procs, NULL,
  90.     "nbap", PRO_BOOL, false, OFF, &blanklines_after_procs, NULL,
  91.     "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines, NULL,
  92.     "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines, NULL,
  93.     "bad", PRO_BOOL, false, ON, &blanklines_after_declarations, NULL,
  94.     "nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations, NULL,
  95.     "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments, NULL,
  96.     "nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments, NULL,
  97.     "ps", PRO_BOOL, false, ON, &pointer_as_binop, NULL,
  98.     "nps", PRO_BOOL, false, OFF, &pointer_as_binop, NULL,
  99.     "troff", PRO_BOOL, false, ON, &troff, NULL,
  100.     "T", PRO_SPECIAL, 0, KEY, 0, NULL,
  101. /* whew! */
  102. /* below two are borrowed from another version of indent, that is gnuindent,
  103.  * but that wouldn't work on my machine and is bad if you don't have enough
  104.  * memory (for those huge files */
  105.     "kr", PRO_SETTINGS, 0, OFF, &kr_format, "-nbad\0-bap\0" \
  106.     "-nbbb\0-nbc\0-br\0-c33\0-cd33\0-ncdb\0-ce\0-ci4\0-cli0\0-d0\0-di1\0-nfc1\0" \
  107.     "-i4\0-ip0\0-l75\0-lp\0-npcs\0-npsl\0-cs\0-nsc\0-nsc\0-nsob\0-nfca\0\0",
  108.     "gnu", PRO_SETTINGS, 0, OFF, &gnu_format, "-nbad\0-bap\0" \
  109.     "-nbbb\0-nbc\0-bl\0-ncdb\0-cs\0-nce\0-di1\0-ndj\0-ei\0-nfc1\0-i2\0-ip5\0-lp\0" \
  110.     "-pcs\0-nps\0-psl\0-nsc\0-nsob\0-cp1\0-nfca\0\0",
  111. /* below I made myself */
  112.     "t", PRO_INT, 8, OFF, &tabsize, NULL,
  113.     0, 0, 0, 0, 0, 0,
  114. };
  115.  
  116. /* set_profile reads $PATH/indent.pro and handles arguments given in this
  117.  * file. */
  118. set_profile()
  119. {
  120.     register FILE *f;
  121.     char fname[BUFSIZ];
  122.     char path[512];        /* hope this is a long enough path! */
  123.     char *p;
  124.     static char pro[] = "indent.pro";
  125.  
  126.     strcpy(path, getenv("PATH"));
  127.  
  128.     while (strlen(path) != 0) {
  129.     /* get head element */
  130.     if ((p = strchr(path, ';')) != NULL) {
  131.         *p = NIL;        /* delimit first string */
  132.         p++;        /* save positon of rest of string */
  133.     }
  134.     /* make path to look in */
  135.     sprintf(fname, "%s\\%s", path, pro);
  136.     sprintf(fname, "%s", path);
  137.     /* check for trailing '\' by looking at the last element of the
  138.      * string */
  139.     if ((strncmp(&fname[strlen(fname) - 1], "\\", 1)) != 0)
  140.         /* there is no trailing delimiter , add it */
  141.         strcat(fname, "\\");
  142.  
  143.     /* add "profile.pro" */
  144.     strcat(fname, pro);
  145.  
  146.     /* move path to next element */
  147.     strcpy(path, p);
  148.  
  149.     /* look in directory */
  150.     if ((f = fopen(fname, "r")) != NULL) {
  151.         scan_profile(f);
  152.         (void) fclose(f);
  153.         return (0);
  154.     }
  155.     }
  156.     fprintf(stderr, "indent: indent.pro not found on path; using defaults\n");
  157. }
  158.  
  159. void
  160.   scan_profile(f)
  161.     register FILE *f;
  162. {
  163.     register char *p, *arg;
  164.     char buf[BUFSIZ];
  165.  
  166.     while (fgets(buf, sizeof buf, f)) {
  167.     if ((p = strchr(buf, '\n')) != NULL)
  168.         *p = 0;
  169.     if (verbose)
  170.         printf("profile: %s\n", buf);
  171.     p = buf;
  172.     for (;;) {
  173.         while (isspace(*p))
  174.         p++;
  175.         if (*p == 0)
  176.         break;
  177.         arg = p;
  178.         while (*p) {
  179.         if (isspace(*p)) {
  180.             *p++ = 0;
  181.             break;
  182.         }
  183.         p++;
  184.         }
  185.         set_option(arg);
  186.     }
  187.     }
  188. }
  189.  
  190. char *param_start;
  191.  
  192. eqin(s1, s2)
  193.     register char *s1;
  194.     register char *s2;
  195. {
  196.     while (*s1) {
  197.     if (*s1++ != *s2++)
  198.         return (false);
  199.     }
  200.     param_start = s2;
  201.     return (true);
  202. }
  203.  
  204. /* Set the defaults. */
  205. void
  206.   set_defaults()
  207. {
  208.     register struct pro *p;
  209.  
  210.     /* Because ps.case_indent is a float, we can't initialize it from the
  211.      * table: */
  212.     ps.case_indent = 0.0;    /* -cli0.0 */
  213.     for (p = pro; p->p_name; p++)
  214.     if (p->p_type != PRO_SPECIAL)
  215.         *p->p_obj = p->p_default;
  216. }
  217.  
  218. void
  219.   set_option(arg)
  220.     register char *arg;
  221. {
  222.     register struct pro *p;
  223.  
  224.     arg++;            /* ignore leading "-" */
  225.     for (p = pro; p->p_name; p++)
  226.     if (*p->p_name == *arg && eqin(p->p_name, arg))
  227.         goto found;
  228.     fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
  229.     exit(1);
  230. found:
  231.     switch (p->p_type) {
  232.  
  233.     case PRO_SPECIAL:
  234.         switch (p->p_special) {
  235.         case IGN:
  236.             break;
  237.  
  238.         case CLI:
  239.             if (*param_start == 0)
  240.             goto need_param;
  241.             ps.case_indent = atof(param_start);
  242.             break;
  243.  
  244.         case STDIN:
  245.             if (input == 0)
  246.             input = stdin;
  247.             if (output == 0)
  248.             output = stdout;
  249.             break;
  250.  
  251.         case KEY:
  252.             if (*param_start == 0)
  253.             goto need_param;
  254.             addkey(param_start, rw_decl);
  255.             break;
  256.  
  257.         default:
  258.             fprintf(stderr, "indent: set_option: internal error: p_special %d\n", p->p_special);
  259.             exit(1);
  260.         }
  261.         break;
  262.  
  263.     case PRO_BOOL:
  264.         if (p->p_special == OFF)
  265.         *p->p_obj = false;
  266.         else
  267.         *p->p_obj = true;
  268.         break;
  269.  
  270.     case PRO_INT:
  271.         if (*param_start == 0) {
  272.     need_param:
  273.         fprintf(stderr, "indent: ``%s'' requires a parameter\n",
  274.             arg - 1);
  275.         exit(1);
  276.         }
  277.         *p->p_obj = atoi(param_start);
  278.         break;
  279.  
  280.     case PRO_SETTINGS:
  281.         {
  282.         char *t;    /* current position */
  283.  
  284.         set_defaults();
  285.  
  286.         t = p->p_data;
  287.         do {
  288.             set_option(t);
  289.             /* advance to character following next NUL */
  290.             while (*t++);
  291.         }
  292.         while (*t);
  293.         }
  294.         break;
  295.  
  296.     default:
  297.         fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
  298.         p->p_type);
  299.         exit(1);
  300.     }
  301. }
  302.